#!/usr/bin/python
# encoding: utf-8
"""
pysxom.py

Created by Jenecai Corvina on 2008-03-08.
Copyright (c) 2008 Jenecai Corvina. All rights reserved.
"""

import sys, os, cgi, re, posixpath, mimetypes
import unittest
from mako.template import Template
from mako.lookup import TemplateLookup
from mako import exceptions
from flup.server.fcgi import WSGIServer
from sqlalchemy import Table, Column, String, Integer, DateTime, MetaData, ForeignKey, create_engine
from sqlalchemy.sql import text
from sqlalchemy.orm import mapper

extensions_map = mimetypes.types_map.copy()
extensions_map.update({
	'': 'text/html',
})

config_map = ({
	'blog_title': 'default',
	'blog_subtitle': 'a pysxom website',
	
	'data_dir': './data',
	'mako_dir': './mako',
	'lib_dir': './xpysxom',
	
	'db_string': 'postgres://seven:wha321XJ@localhost/icekami',
})

class Pysxom:
	def __init__(self, tldir=config_map['data_dir'], tlmoddir=config_map['mako_dir']):
		self.lookup = TemplateLookup(directories=[tldir], module_directory=tlmoddir)
		self.template = None
		self.db = PysxomDB()
		pass
	
	def getfield(self, f):
		if isinstance(f, list):
			return [getfield(x) for x in f]
		else:
			return f.value
	
	def webserver(self, environ, start_response):
		fieldstorage = cgi.FieldStorage(
			fp = environ['wsgi.input'],
			environ = environ,
			keep_blank_values = True
		)
		
		d = dict([(k, self.getfield(fieldstorage[k])) for k in fieldstorage])
		
		uri = environ.get('PATH_INFO', '/')
		
		if not uri:
			uri = '/index.html'
		else:
			uri = re.sub(r'^/$', '/index.html', uri)
		
		if re.match(r'.*\.html$', uri):
			try:
				template = self.serve_template(uri)
				start_response('200 OK', [('Content-Type', 'text/html')])
				return [template]
			except:
				try:
					from xpysxom.pyblosxom import PyBlosxom 
					start_response('404 Not Found', [])
					return ["Can't find template %s" % uri]
				except:
					start_response('404 Not Found', [])
					return ["Can't find blog entry %s" % uri]
		else:
			u = re.sub(r'^\/+', '', uri)
			filename = os.path.join('./data/', u)
			start_response('200 OK', [('Content-Type', self.guess_type(uri))])
			return [file(filename).read()]
	
	def guess_type(self, path):
		base, ext = posixpath.splitext(path)
		if ext in extensions_map:
			return extensions_map[ext]
		ext = ext.lower()
		if ext in extensions_map[ext]:
			return extensions_map[ext]
		else:
			return extensions_map['']
	
	def serve_template(self, templatename, **kwargs):
		try:
			self.template = self.lookup.get_template(templatename)
			return self.template.render(**kwargs)
		except:
			return exceptions.html_error_template().render(**kwargs)
	
	def run(self):
		WSGIServer(self.webserver).run()
		self.db.connection.close()

class PysxomDB:
	def __init__(self, dbstring=config_map['db_string'], **kwargs):
		"""docstring for __init__"""
		self.dbstring = dbstring
		self.metadata = MetaData()
		self.engine = create_engine(dbstring, **kwargs)
		self.metadata.bind = self.engine
		self.connection = self.engine.connect()
		self.tables = self.discovery()
	
	def discovery(self):
		table_l = []
		t = text("""SELECT tablename FROM pg_tables;""")
		res = self.connection.execute(t).fetchall()
		for row in res:
			if row[0] not in ['system', 'variables']:
				if re.match(r'^l_', row[0]):
					table_l += [ row[0] ]
		table_l += [ 'system', 'variables' ]
		
		d = dict()
		for table in table_l:
			d[table] = Table(table, self.metadata, autoload=True)
			self.metadata.create_all(self.engine)
			##mapper(eval("table"), d[table])
			##print "DEBUG: %s" % table
		return (d)
		
class PysxomTests(unittest.TestCase):
	def setUp(self):
		pass


if __name__ == '__main__':
	##unittest.main()
	server = Pysxom()
	server.run()